home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 9582 < prev    next >
Encoding:
Text File  |  1996-08-05  |  6.1 KB  |  178 lines

  1. Path: lade.news.pipex.net!pipex!dircon!usenet
  2. From: sridgway@dircon.co.uk (Steven Ridgway)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: passing arrays and returning structs
  5. Date: Mon, 11 Mar 1996 21:50:44 GMT
  6. Organization: Direct Connection
  7. Message-ID: <4i27eo$202@newsgate.dircon.co.uk>
  8. References: <4i2128$69d@news2.acs.oakland.edu>
  9. NNTP-Posting-Host: gw4-129.pool.dircon.co.uk
  10. X-Newsreader: Forte Free Agent 1.0.82
  11.  
  12. jggoslin@vela.acs.oakland.edu (Monument) wrote:
  13.  
  14. >I have been wracking my brains over this one.  I needed to write a
  15. >program to do the transitive closure of a binary relation matrix, no
  16. >problems encountered during that.  However, I tried to streamline the
  17. >code, by putting the transitive closure algorithm in it's own
  18. >function.  When I did this, I tried to pass the initially read in
  19. >matrix into the function as an argument, and return a message buffer
  20. >to the calling function.
  21.  
  22. >I got a mess of errors, included below for your perusal.  If anyone
  23. >has any suggestions on how I could get the pointers and returns fixed,
  24. >I would sincerely appreciate it.  Post or email, since I read both
  25. >regularly.
  26.  
  27. >===client.h===
  28. >#include <stdio.h>
  29. >#include <sys/errno.h>
  30. >#include <sys/ipc.h>
  31. >#include <sys/msg.h>
  32. >#include <sys/types.h>
  33.  
  34. >#define PATH "./server"
  35. >#define PROJ 'B'
  36. >#define PERMS 0666
  37. >#define MAXSZ 200
  38.  
  39. >key_t key;
  40. >int msgqid;
  41.  
  42. >typedef struct my_msgbuf {
  43. >    long mtype;
  44. >    int pid;
  45. >    int size;
  46. >    int data[2*MAXSZ];
  47. >} Message;
  48. >===client.h===
  49.  
  50. >===client.c===
  51. >// header files
  52. >#include "client.h"
  53.  
  54. >// function prototypes
  55. >struct Message transitive_closure(int matrix[]);
  56.  
  57. >// MAINLINE
  58. >int main(int argc, char *argv[])
  59. >{
  60. >[I am going to delete a bunch of code here that is irrelevant to the
  61. >problem, since I know it works.  All the code I delete does is reads
  62. >in the matrix]
  63.  
  64. >[here is the relevant call]
  65. >    // get the transitive closure
  66. >    buffer = transitive_closure(matrix);
  67.  
  68. >    // print out results
  69. >    puts("Transitive Closure:");
  70. >    for (i=0; i<buffer.size; i++)
  71. >    {
  72. >        for (j=0; j<buffer.size; j++)
  73. >            printf(" %d", buffer.data[i*buffer.size+j]);
  74. >        printf("\n");
  75. >    }
  76.  
  77. >    // successful finish
  78. >    return 0;
  79. >}
  80.  
  81. >struct Message* transitive_closure(int matrix[])
  82. >{
  83. >    int i, j, size;
  84. >    Message buffer;
  85. >    pid_t pid;
  86.  
  87. >[here do I refer to the subtypes in the correct manner?  "." vs. "->"
  88. >is what I'm talking about]
  89.  
  90. >    buffer.mtype=1L;
  91. >    buffer.pid=pid;
  92. >    buffer.size=size;
  93. >    for (i=0; i<size; i++)
  94. >        for (j=0; j<size; j++)
  95. >            buffer.data[i*size+j]=matrix[i*size+j];
  96.  
  97. >[is the return type correct?]
  98. >    return *buffer;
  99. >}
  100. >===client.c===
  101.  
  102. >===ERRORS===
  103. >cc -g -c client.c
  104. >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 58: Functions cannot return a non-object type
  105. >     buffer = transitive_closure(matrix);
  106. >     ---------------------------^
  107. >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 58: Reference an expression of void type or an incomplete type.
  108. >     buffer = transitive_closure(matrix);
  109. >     ---------------------------^
  110. >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 73: redeclaration of 'transitive_closure'; previous declaration at line 11 in file 'client.c'
  111. > struct Message* transitive_closure(int matrix[])
  112. > ----------------^
  113. >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 73: Incompatible function return type for this function
  114. > struct Message* transitive_closure(int matrix[])
  115. > ----------------------------------^
  116. >/usr/lib/cmplrs/cc/cfe: Error: client.c, line 109: Dereference a non-pointer
  117. >     return *buffer;
  118. >     --------^
  119. >*** Exit 1
  120. >Stop.
  121. >===ERRORS===
  122.  
  123. > ----------------------------------------------------------------------------
  124. >|          Jeff Goslin - Monument           | "Oh Bentson, you are so        |
  125. >|      jggoslin@vela.acs.oakland.edu        |  mercifully free from the      |
  126. >|                                           |  ravages of intellect."        |
  127. >| http://www.acs.oakland.edu/links/jggoslin |   --Evil, The Time Bandits     |
  128. > ----------------------------------------------------------------------------
  129. >|   how come everyone elses religion is a cult but your cult is a religion   |
  130. > ----------------------------------------------------------------------------
  131.  
  132. Hi,
  133.  
  134. You have at least three problems here.
  135.  
  136. 1.     You should prototype your function transitive_closure before
  137. you use it. ie add the line :
  138. struct Message* transitive_closure(int matrix[]);
  139. at the top of your file or in a header (before you reference it but
  140. after you define Message anyway).
  141. Without this the compiler assumes it returns int, then whines when you
  142. define it as something else.
  143.  
  144. 2.    Your return in transistive_matrix is screwed up. If you want
  145. to return a pointer to a Message (as your function definition implies)
  146. you should use &buffer not *buffer. However this will not solve
  147. everything as there is a more subtle problem ...
  148.  
  149. 3.    In transitive_matrix you are trying to return a pointer to a
  150. Message, however your buffer variable is a local variable, ie it
  151. exists only during the scope of that function. If you return a pointer
  152. to your local variable you will be returning a pointer to some random
  153. place on the stack, which will be overwritten by other things. If you
  154. really need to return a Message, you can either :
  155. a.  Change the function to return a Message direct (ie a structure).
  156. This will work, but is not a good idea as you are copying a lot of
  157. data on and off the stack.
  158. b.  Dynamically allocate a Message within transistive_matrix (ie
  159. Message *buffer = malloc(sizeof(Message));   ) then return that.
  160. However you then have to be carefull that you free it explicitly at
  161. the appropriate time.
  162. c. Make buffer a static variable of transitive_matrix. Thus the memory
  163. for buffer is permanent and you can throw pointers to it around as you
  164. like. The very serious disadvantage to this is that there is only one
  165. Message around at any one time. Thus if you want to call
  166. transitive_matrix lots of times, and compare the resultant messages
  167. you will be stuffed.
  168. d. Change transitive_matrix so that instead of returning a Message, it
  169. takes a pointer to one as another argument. It is then up to the
  170. caller to get allocate (dynamically or on the stack) a Message. This
  171. sort of problem happens again and again in big C programs, and in my
  172. experience option d. works is the best.
  173.  
  174. Hope this help.
  175.  
  176. Steven Ridgway (sridgway@dircon.co.uk)
  177.  
  178.